package com.yunda.teamspinner.localcomponent.popupwindow;

import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.LinearLayout;
import android.widget.PopupWindow;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.gson.Gson;
import com.yunda.teamspinner.R;
import com.yunda.teamspinner.localcomponent.YdSpinner;
import com.yunda.teamspinner.localcomponent.adapter.SpinnerAdapter;
import com.yunda.teamspinner.localcomponent.entity.SpinnerType;
import com.yunda.teamspinner.localcomponent.sp_interface.ISpinnerItemValue;
import com.yunda.teamspinner.localcomponent.sp_interface.OnSpItemClickListener;
import com.yunda.util.DensityUtil;
import com.yunda.util.ScreenUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import static com.yunda.util.CopyUtil.deepCopy;

/**
 * copyright (C), 2022, 运达科技有限公司
 * fileName SexPopWindow
 *
 * @author 王玺权
 * date 2022-05-13 17:16 参考
 * description https://blog.csdn.net/qq_46237697/article/details/112647615
 * history
 */
public class YdPopWindow<T extends ISpinnerItemValue> extends PopupWindow implements OnSpItemClickListener<T> {
    private RecyclerView rv;
    private LinearLayout ll;
    private LinearLayoutManager manager;
    private SpinnerAdapter spinnerAdapter;
    private Context mContext;
    private List<T> list;
    private List<T> allList;
    private String mType;
    private Boolean mIsSingle;
    private YdSpinner ydSpinner;
    private Window mWindow;
    public YdPopWindow(Context context) {

    }

    /**
     * 兼容在fragment中使用报错
     * Android ContextThemeWrapper cannot be cast to android.app.Activity
     * @param cont
     * @return
     */
    private  Activity scanForActivity(Context cont) {
        if (cont == null){
            return null;
        }
        else if (cont instanceof Activity){
            return (Activity)cont;
        }
        else if (cont instanceof ContextWrapper){
            return scanForActivity(((ContextWrapper)cont).getBaseContext());
        }
        return null;
    }

    public YdPopWindow(Context context, List<T> list, String type, Boolean isSingle,YdSpinner spinner) {
        Activity activity = scanForActivity(context);
        LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.mContext=activity;
        this.mType=type;
        this.mIsSingle=isSingle;
        this.list=list;
        this.allList=list;
        this.ydSpinner=spinner;
        if(mType.equals(SpinnerType.SERCH_TYPE)){
            mIsSingle=true;
        }
        View content = inflater.inflate(R.layout.spinner_item, null);
        initview(content);
        this.setContentView(content);
        //xml布局需要在外面在嵌套一层    不然布局文件不是你想要的
        this.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
        this.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);

        this.setOutsideTouchable(true);
        this.update();//刷新状态
        ColorDrawable dw = new ColorDrawable(0000000000);//半透明
        this.setBackgroundDrawable(dw);// 点back键和其他地方使其消失,设置了这个才能触发OnDismisslistener ，设置其他控件变化等操作
//        this.setAnimationStyle(R.style.AnimationPreview); // 设置SelectPicPopupWindow弹出窗体动画效果
        mWindow = ((Activity)mContext).getWindow();
    }

    private void initview(View v) {
        manager=new LinearLayoutManager(mContext,LinearLayoutManager.VERTICAL,false);
        spinnerAdapter=new SpinnerAdapter(R.layout.item_spinner,list,mType,mIsSingle,this::onSpItemClick,this);
        rv=v.findViewById(R.id.rv);
        rv.setLayoutManager(manager);
        rv.setAdapter(spinnerAdapter);
    }

    //显示popupWindow
    public void showPopupWindow(View v) {
        if (!this.isShowing()) {
            //   this.showAtLocation(v, Gravity.BOTTOM, 0, 0);        //相对于屏幕的
//            this.showAsDropDown(v, 0, 5);  //相对于某个控件的位置
            showWithAnchorView(v);
            spinnerAdapter.updateCheckList();
        } else {
            this.dismiss();
        }
    }
    /**
     * 显示在锚点上方或者下方
     *
     * @param anchorView
     */
    private void showWithAnchorView(View anchorView) {
        int[] coordinate = calculatePopWindowPos(anchorView, getContentView());

        if (!isShowing()) {
            showAtLocation(anchorView, 0, coordinate[0], coordinate[1]);
//            showAtLocation(mWindow.getDecorView(), 0, coordinate[0], coordinate[1]);
        } else {
            update(coordinate[0], coordinate[1], getWidth(), getHeight());
        }

    }

    private int[] calculatePopWindowPos(final View anchorView, final View contentView) {

        final int[] windowPos = new int[2];
        final int[] anchorLoc = new int[2];
        final int[] actLoc = new int[2];//activity的坐标(屏幕中)
        View decorView = mWindow.getDecorView();
        anchorView.getLocationOnScreen(anchorLoc);        // 获取锚点View在屏幕上的左上角坐标位置
        decorView.getLocationOnScreen(actLoc);//屏幕高度：内容区域(Activity)、状态栏、导航栏

        //window可视化区域Rect，#不包含状态栏#
        Rect rect = new Rect();
        mWindow.getDecorView().getWindowVisibleDisplayFrame(rect);
        final int actualHeight = rect.bottom - rect.top;//考虑输入框时：输入框上方的区域宽高,
        final int actualWidth = rect.right - rect.left;
        final int statusH = rect.top;//状态栏高度

        final int anchorHeight = anchorView.getHeight();
        // 获取屏幕的高宽
        final int decorViewHeight = decorView.getHeight();
//        final int actWidth = actView.getWidth();

        long timeStart = System.currentTimeMillis();
        int heightM = View.MeasureSpec.makeMeasureSpec(decorViewHeight, View.MeasureSpec.AT_MOST);
        contentView.measure(View.MeasureSpec.UNSPECIFIED, heightM);//可用高度不包括状态栏高度
//      contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);//可用高度不包括状态栏高度,list元素众多时，计算异常耗时
        long timeEnd = System.currentTimeMillis();
        Log.e("开始结束时间","time-cost=" + (timeEnd - timeStart) / 1000f + "s");

        // 计算contentView的高宽
        final int popWindowHeight = contentView.getMeasuredHeight();
        final int popWindowWidth = contentView.getMeasuredWidth();
        // 判断需要向上弹出还是向下弹出显示
        int anchroLocYInScr = anchorLoc[1] - actLoc[1];//锚点在Activity内容布局中的Y坐标(锚点View位于Activity界面中)
        boolean isNeedShowUp = false;
        if (rect.bottom - anchroLocYInScr - anchorHeight >= popWindowHeight) {//anchorView "下方"剩余高度(Activity中,不包含导航栏)
            isNeedShowUp = false;
            setHeight(popWindowHeight);
        } else if (anchroLocYInScr - rect.top >= popWindowHeight) {//anchorView "上方"剩余高度，不包含状态栏
            isNeedShowUp = true;
            setHeight(popWindowHeight+ DensityUtil.dp2px(mContext,0));
        } else if (anchroLocYInScr >= rect.bottom - anchroLocYInScr - anchorHeight) {//PopWindow高度过大，上边可用高度大，显示在上边
            isNeedShowUp = true;
            setHeight(anchroLocYInScr - rect.top+ DensityUtil.dp2px(mContext,0));//重置PopWindow高度

            /*通过设置contentView不能达到修改窗体宽高的需求*/
            /*ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, anchroLocYInActContView);
            contentView.setLayoutParams(lp);
            contentView.requestLayout();*/

        } else if (rect.bottom - anchroLocYInScr - anchorHeight > anchroLocYInScr) {//ContentView高度过大，下边可用高度大，显示在下边
            isNeedShowUp = false;
            setHeight(rect.bottom - anchroLocYInScr - anchorHeight);//重置PopWindow高度

            /*通过设置contentView不能达到修改窗体宽高的需求*/
            /*ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, actContentViewHeight - anchroLocYInActContView - anchorHeight-120);
            contentView.setLayoutParams(lp);
            contentView.requestLayout();*/
        }


        if (isNeedShowUp) {
            //状态栏显示不了window
            windowPos[0] = anchorLoc[0];
            windowPos[1] = anchorLoc[1] - rect.top - popWindowHeight < 0 ? 0 : anchorLoc[1] - rect.top - popWindowHeight+ DensityUtil.dp2px(mContext,26)-5;
        } else {
            windowPos[0] = anchorLoc[0];
            windowPos[1] = anchorLoc[1] + anchorHeight+5;
        }
        return windowPos;
    }


    @Override
    public void setWidth(int width) {
        super.setWidth(width);
    }

    public List<T> getCheckBoxList(){
        return spinnerAdapter.getCheckBoxList();
    }

    /**
     * 点击回调事件
     * @param position
     */
    @Override
    public void onSpItemClick(int position, List<T> heroBeanList) {
        Log.e("点击的是",position+"...");
        ydSpinner.setSelectPos(position,heroBeanList);
        if(mIsSingle){
            dismiss();
        }
    }

    /**
     * 更新数据
     * @param heroBeanList
     */
    public void updateData(List<T> heroBeanList){
        List<T> temp=new ArrayList<>();
        for (int i = 0; i <allList.size() ; i++) {
            for (int j = 0; j <heroBeanList.size() ; j++) {
                if(((ISpinnerItemValue)(allList.get(i))).getItem().equals(((ISpinnerItemValue)heroBeanList.get(j)).getItem())){
                    temp.add(heroBeanList.get(j));
                }
            }
        }

        list.clear();
        this.list=temp;
        Log.e("更新数据",new Gson().toJson(list)+"...");

        spinnerAdapter.cleanData();

        spinnerAdapter.getData().clear();
        spinnerAdapter.addData(list);
        spinnerAdapter.notifyDataSetChanged();
        setViewSize(rv);
    }



    public List<T> localData=new ArrayList<>();
    public void setData(List<T> datas){
        this.list=datas;
        this.allList=datas;

        spinnerAdapter.getData().clear();
        spinnerAdapter.addData(list);
        spinnerAdapter.notifyDataSetChanged();
        setViewSize(rv);

        localData=deepCopy(datas);
    }

    public List<T> getLocalData(){
        return localData;
    }

    /**
     * 设置view大小
     * @param view view
     */
    public void setViewSize(View view){
        ScreenUtil.hideKeyboard(mContext,view.getWindowToken());
        //阈值
        int windowHeight = getWindowHeight()*4/10;
        //item高度
        int height1 = list.size()* DensityUtil.dp2px(mContext,34);


        Log.e("高度对比",windowHeight+"--"+height1);
        ViewGroup.LayoutParams layoutParams=view.getLayoutParams();
        layoutParams.width= ViewGroup.LayoutParams.MATCH_PARENT;
        if(height1>windowHeight){
            layoutParams.height=windowHeight;
        }else {
            layoutParams.height= ViewGroup.LayoutParams.WRAP_CONTENT;
        }
        view.setLayoutParams(layoutParams);
    }

    private int getWindowHeight(){
        DisplayMetrics metric = new DisplayMetrics();

        ((Activity)mContext).getWindowManager().getDefaultDisplay().getMetrics(metric);
        int width = metric.widthPixels;     // 屏幕宽度（像素）
        int height = metric.heightPixels;   // 屏幕高度（像素）
        float density = metric.density;      // 屏幕密度（0.75 / 1.0 / 1.5）
        int densityDpi = metric.densityDpi;  // 屏幕密度DPI（120 / 160 / 240）
        return height;
    }

    /**
     * 选中位置
     * @param position
     */
    public void checkListPosition(List<Integer> position){
        if(position.size()<=0){
            return;
        }
        spinnerAdapter.checkListPosition(position);

    }
    public void checkPosition(int position){
        if(position<0){
            return;
        }
        spinnerAdapter.checkPosition(position);
    }

    public void checkObj(T t){
        if(t==null){
            return;
        }
        spinnerAdapter.checkObj(t);
    }



    /**
     * 选中集合
     * @param data
     */
    public void checkListObj(List<T> data){
        if(data.size()<=0){
            return;
        }
        spinnerAdapter.checkListObj(data);
    }


    /**
     * 重置
     */
    public void reset() {
        spinnerAdapter.resetData();
        spinnerAdapter.getData().clear();
        spinnerAdapter.notifyDataSetChanged();
    }

    /**
     * 重置
     */
    public void recovery() {
        spinnerAdapter.recoveryData();
    }
}
